package com.haiheng.module_main.mode

import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.viewModelScope
import com.haiheng.common.api.API
import com.haiheng.common.constant.AppConstant
import com.haiheng.library.log.LogUtils
import com.haiheng.library.log.LogWriter
import com.haiheng.library_base.db.BookInfoBean
import com.haiheng.library_base.db.BookShiftingRecordTable
import com.haiheng.library_base.db.BookWithdrawalRecordTable
import com.haiheng.library_base.db.KV
import com.haiheng.library_base.db.KVDatabase
import com.haiheng.library_base.db.RecordTable
import com.haiheng.library_base.db.SmartEploymentRecordTable
import com.haiheng.library_base.http.Domain
import com.haiheng.library_base.http.HttpRequest
import com.haiheng.library_base.http.HttpResponse
import com.haiheng.library_base.http.api
import com.haiheng.library_base.http.postJson
import com.haiheng.library_base.model.BaseViewModel
import com.haiheng.library_base.utils.DateUtils
import com.haiheng.library_base.utils.SPUtils
import com.haiheng.module_main.bean.req.Asset
import com.haiheng.module_main.bean.req.AssetOffInfo
import com.haiheng.module_main.bean.req.BookAssetLocationReq
import com.haiheng.module_main.bean.req.BookAssetOffLocationReq
import com.haiheng.module_main.bean.req.BookInfoPageRes
import com.haiheng.module_main.bean.req.BookShiftingReq
import com.haiheng.module_main.bean.req.LayLocationInfo
import com.haiheng.module_main.bean.req.OnselfByCallNumberReq
import com.haiheng.module_main.bean.req.PageQueryReq
import com.haiheng.module_main.bean.req.ShiftingInfo
import com.haiheng.module_main.bean.req.SourceInfo
import com.haiheng.module_main.bean.req.Wherejson
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
import kotlinx.coroutines.runBlocking
import kotlinx.coroutines.withContext

/**
 *
 * @Des:
 * @Author: hwz
 * @Date:2023/7/19 0019
 * @Version: 1.0
 */
class DataSynchronizationViewModel : BaseViewModel() {
    var showMsg = MutableLiveData<String>()
    var totolNumber = MutableLiveData<Int>(0)
    var synBooInfoNumber = MutableLiveData<Int>(0)
    var synRecordNumber = MutableLiveData<Int>(0)
    var synSmartRecordNumber = MutableLiveData<Int>(0)
    var synWithdrawalRecordNumber = MutableLiveData<Int>(0)
    var synBookShiftingRecordNumber = MutableLiveData<Int>(0)
    var synProgressSize = MutableLiveData<Int>()
    var synFinish = MutableLiveData<Boolean>()
    var smartRecordList = MutableLiveData<List<SmartEploymentRecordTable>>()
    var bookWithdrawalRecordList = MutableLiveData<List<BookWithdrawalRecordTable>>()
    var bookShiftingRecordList = MutableLiveData<List<BookShiftingRecordTable>>()
    var recordList = MutableLiveData<List<RecordTable>>()

    /**
     * 检查是否有同步数据
     *
     * @return
     */
    fun checkSyn(): Boolean = runBlocking {
        var hasData = false
        withContext(Dispatchers.IO) {
            var db  = KVDatabase.getDb()
            val recordListResult = db.getRecordDao().queryAll()
            if (recordListResult.size > 0) {
                recordList.postValue(recordListResult)
                hasData = true
                return@withContext
            }

            val smartRecordListResult = db.getSmartEploymentRecordDao().queryAll()
            if (smartRecordListResult.size > 0) {
                smartRecordList.postValue(smartRecordListResult)
                hasData = true
                return@withContext
            }

            var bookWithDrawalRecordResul  = db.getBookWithdrawalRecordDao().queryAll()
            if (bookWithDrawalRecordResul.size > 0){
                bookWithdrawalRecordList.postValue(bookWithDrawalRecordResul)
                hasData = true
                return@withContext
            }

            var bookShiftingRecordResult = db.getBookShiftingRecordDao().queryAll()
            if (bookShiftingRecordResult.size > 0){
                bookShiftingRecordList.postValue(bookShiftingRecordResult)
                hasData = true
                return@withContext
            }
        }
        return@runBlocking hasData
    }
    /**
     * 上传智慧上架记录
     *
     */
    fun synSmartRecord(){
        api {
            totolNumber.postValue(smartRecordList.value?.size ?: 0)
            synProgressSize.postValue(0)
            smartRecordList.value?.forEach {
                var req = OnselfByCallNumberReq()
                req.orgCode = it.orgCode.toString()
                req.onSelfObjNo = it.onSelfObjNo.toString()         //上架目标编号  书架层号 或  书架号(真实物理层架号)
                req.onSelfObjType = it.onSelfObjType //上架目标类型  0书架层号  1书架号
                req.startCallNu = it.startCallNu.toString()
                req.endCallNu = it.endCallNu.toString()
                req.logUser = it.logUser.toString()
                val request = HttpRequest(API.PATH.ONSELF_BY_CALLNUMBER)
                    .putHeader(Domain.KEY_NAME, Domain.VALUE_DEFUlT)
                    .putHeader(API.PARAM.PARAM_HEADER_TOKEN,AppConstant.getToken())
                    .setJsonObjec(req)
                var response = postJson<HttpResponse>(request)
                if (response.isSuccess == true){
                    synProgressSize.postValue((synProgressSize.value ?: 0) + 1)
                    KVDatabase.getDb().getSmartEploymentRecordDao().delete(it)
                    LogUtils.e("上传智慧上架成功：${response.toJson()}")
                }else{
                    LogUtils.w("上传智慧上架信息失败:${response.toJson()}")
                }
            }
            synSmartRecordNumber.postValue(synProgressSize.value)
            synFinish.postValue(true)
            showMsg.postValue("上传智慧上架记录完成")
        }
    }

    /**
     * 上传单上架记录
     */
    fun synShelpRecord(){
        api {
            totolNumber.postValue(recordList.value?.size ?: 0)
            synProgressSize.postValue(0)
            recordList.value?.forEachIndexed { index, value ->
                var assets = arrayListOf<Asset>()
                var asset = Asset()
                asset.barCode = value.barCode.toString()
                asset.currentPlaceIndex = value.currentPlaceIndex
                assets.add(asset)

                var bookAssetLocationReq = BookAssetLocationReq()
                var layLocationInfos = arrayListOf<LayLocationInfo>()
                var layLocationInfo = LayLocationInfo()
                layLocationInfo.outLayNo = value.outLayNo//真实层架号
                layLocationInfo.containerIdType = 4 //4为真实层架号  5为rfid智能书架层架号 0系统层ID
                layLocationInfo.assets = assets
                layLocationInfos.add(layLocationInfo)
                bookAssetLocationReq.layLocationInfos  = layLocationInfos
                var sourceInfo = SourceInfo()
                sourceInfo.orgCode = AppConstant.getLibraryCode()
                sourceInfo.dataSourceId = AppConstant.getMachineUuid()
                sourceInfo.dataSourceType = "6" //数据起源  1盘点  2自动盘点  3条码绑定  4走接口上传   5内部联动  6手持 7盘点车
                sourceInfo.deviceMac = AppConstant.getMachineUuid()
                sourceInfo.locationType = value.locationType //1 整层盘点(如不在本次列表会离架)    2 单一上架   3整层上架（不阅读）
                bookAssetLocationReq.sourceInfo = sourceInfo
                val request = HttpRequest(API.PATH.BOOK_ASSET_LOCATION)
                    .putHeader(Domain.KEY_NAME,Domain.VALUE_DEFUlT)
                    .putHeader(API.PARAM.PARAM_HEADER_TOKEN,AppConstant.getToken())
                    .setJsonObjec(bookAssetLocationReq)
                var response  = postJson<HttpResponse>(request)
                if (response.isSuccess == true){
                    synProgressSize.postValue((synProgressSize.value ?: 0) + 1)
                    KVDatabase.getDb().getRecordDao().delete(value)
                    LogUtils.e("上传上架成功：${value.barCode}")
                }else{
                    LogUtils.w("上传上架信息失败:${value.barCode}")
                    showMsg.postValue("上传上架信息失败：${response.toJson()}")
                }
            }
            synRecordNumber.postValue(synProgressSize.value)
            synFinish.postValue(true)
            showMsg.postValue("上传上架记录完成")
        }
    }

    /**
     * 同步下架记录
     *
     */
    fun synBookWithdrawal(){
        viewModelScope.launch(Dispatchers.IO) {
            totolNumber.postValue(bookWithdrawalRecordList.value?.size ?: 0)
            synProgressSize.postValue(0)
            var failNum = 0
            bookWithdrawalRecordList.value?.forEach {
                var req =  BookAssetOffLocationReq()
                var sourceInfo = SourceInfo()
                sourceInfo.dataSourceType = it.dataSourceType.toString()
                sourceInfo.orgCode = it.orgCode.toString()
                var assetOffInfos = arrayListOf<AssetOffInfo>()
                var assetOffInfo = AssetOffInfo()
                var assets = arrayListOf<Asset>()
                var asset = Asset()
                asset.barCode = it.barCode.toString()
                assets.add(asset)
                assetOffInfo.assets = assets
                assetOffInfos.add(assetOffInfo)
                req.sourceInfo = sourceInfo
                req.assetOffType =it.assetOffType // 0下架（书列表）  1下架（按层）   2剔旧（书列表）
                req.assetOffInfos =  assetOffInfos
                val request = HttpRequest(API.PATH.BOOK_ASSET_OFF_LOCATION)
                    .putHeader(Domain.KEY_NAME, Domain.VALUE_DEFUlT)
                    .putHeader(API.PARAM.PARAM_HEADER_TOKEN, AppConstant.getToken())
                    .setJsonObjec(req)
                var response  = postJson<HttpResponse>(request)
                if (response.isSuccess == true ){
                    synProgressSize.postValue((synProgressSize.value ?: 0) + 1)
                    KVDatabase.getDb().getBookWithdrawalRecordDao().delete(it)
                    LogUtils.d("同步下架、剔旧记录成功:${it.barCode}")
                }else{
                    LogWriter.e("同步书籍下架、剔旧失败:${response.toJson()}")
                    failNum = failNum.plus(1)
                    showMsg.postValue("同步书籍下架失败:${response.toJson()}")
                }
            }
            LogUtils.d("上传下架记录完成")
            synWithdrawalRecordNumber.postValue(synProgressSize.value)
            synFinish.postValue(true)
            showMsg.postValue("上传下架、剔旧记录完成，失败：${failNum}条")
        }
    }
    fun synBookShif(){
        viewModelScope.launch(Dispatchers.IO) {
            totolNumber.postValue(bookShiftingRecordList.value?.size ?: 0)
            synProgressSize.postValue(0)
            bookShiftingRecordList.value?.forEach {
                var req = BookShiftingReq()
                req.orgCode = it.orgCode.toString()
                var shiftingInfos = arrayListOf<ShiftingInfo>()
                var shiftingInfo = ShiftingInfo()
                shiftingInfo.newContainerSubId = it.newContainerSubId
                shiftingInfo.srcContainerSubId = it.srcContainerSubId
                shiftingInfos.add(shiftingInfo)
                req.shiftingInfos = shiftingInfos
                val request = HttpRequest(API.PATH.BOOK_SHIFTING)
                    .putHeader(Domain.KEY_NAME,Domain.VALUE_DEFUlT)
                    .putHeader(API.PARAM.PARAM_HEADER_TOKEN,AppConstant.getToken())
                    .setJsonObjec(req)
                var response  = postJson<HttpResponse>(request)
                if (response.isSuccess == true ){
                    synProgressSize.postValue((synProgressSize.value ?: 0) + 1)
                    KVDatabase.getDb().getBookShiftingRecordDao().delete(it)
                    LogUtils.d("同步倒架记录成功:${it.toString()}")
                }else{
                    LogWriter.e("同步倒架失败:${response.toJson()}")
                    showMsg.postValue("同步倒架失败:${response.toJson()}")
                }
            }
            LogUtils.d("上传倒架记录完成")
            synBookShiftingRecordNumber.postValue(synProgressSize.value)
            synFinish.postValue(true)
            showMsg.postValue("上传倒架记录完成")
        }
    }
    fun synBookByPage(page: Int) {
        //同步之前先检查本地是否有未上传的操作记录
        viewModelScope.launch(Dispatchers.IO) {
            if (checkSyn()) return@launch
            try {
                var pageQueryReq = PageQueryReq()
                pageQueryReq.page = page
                pageQueryReq.orderByFiled =
                    "CurrentContainerId,CurrentContainerSubId,CurrentPlaceIndex,Id asc"
                pageQueryReq.length = 10
                var wherejson = arrayListOf<Wherejson>()
                var orgCodejson = Wherejson()
                orgCodejson.conditionalType = 0 //0精确查询，1，模糊查询
                orgCodejson.fieldName = "OrgCode"
                orgCodejson.fieldValue = AppConstant.getLibraryCode()
                wherejson.add(orgCodejson)
                pageQueryReq.wherejson = wherejson
                val request = HttpRequest(API.PATH.SEARCH_MORE_INFO)
                    .putHeader(Domain.KEY_NAME, Domain.VALUE_DEFUlT)
                    .putHeader(API.PARAM.PARAM_HEADER_TOKEN, AppConstant.getToken())
                    .setJsonObjec(pageQueryReq)
                LogUtils.e("开始同步第${page}页书籍")
                var response = postJson<BookInfoPageRes>(request)
                if (response.isSuccess == true && response.data != null && response.data.size > 0) {
                    if (page == 1) {
                        totolNumber.postValue(response.iTotalRecords.toInt())
                        synProgressSize.postValue(0)
                    }
                    response.data.forEach {
                        KVDatabase.getDb().bookInfoDao().insertBookInfo(it)
                    }
                    synProgressSize.postValue((synProgressSize.value ?: 0) + response.data.size)
                    LogUtils.e("同步第${page}页书籍成功：${response.data.size}")
                    synBookByPage(page + 1)
                    // TODO: 测试代码
                /*    totolNumber.postValue(200*10000)
                    synProgressSize.postValue(0)
                    var fistBook = response.data.first()
                    for (i in 0 until 200) {
                        var list = arrayListOf<BookInfoBean>()
                        for(j in 0  until 100000){
                            var b = BookInfoBean()
                            b.bookTitle = fistBook.bookTitle
                            b.bookOnShelfStatus = fistBook.bookOnShelfStatus
                            b.barCode = "${i}${j}"
                            b.author = fistBook.author
//                        b.fixedContainerSub = fistBook.fixedContainerSub
//                        b.currentContainerSub = fistBook.currentContainerSub
                            b.publisher= fistBook.publisher
                            b.bookSInfo = fistBook.bookSInfo
                            b.bookImgUrl = fistBook.bookImgUrl
                            list.add(b)
                        }
                        LogUtils.d("正在同步第${i*100000}条数据")
                        KVDatabase.getDb().bookInfoDao().insertBookInfo(*list.toTypedArray())
                        synProgressSize.postValue((synProgressSize.value ?: 0) +100000)
                    }
                    synBooInfoNumber.postValue(synProgressSize.value)
                    showMsg.postValue("同步书籍信息完成")
                    synFinish.postValue(true)*/
                } else if (response.isSuccess == true) {
                    synBooInfoNumber.postValue(synProgressSize.value)
                    showMsg.postValue("同步书籍信息完成")
                    SPUtils.getInstance().put(AppConstant.SP_LAST_SYN_TIME,
                        DateUtils.getTime(System.currentTimeMillis()))
                    synFinish.postValue(true)
                    LogWriter.e("同步完成")
                } else {
                    showMsg.postValue("获取第${page}页信息失败:${response.toJson()}")
                    LogWriter.e("获取第${page}页信息失败:${response.toJson()}")
                }
            } catch (ex: Exception) {
                showMsg.postValue(ex.toString())
                LogWriter.e("同步第${page}页信息异常:${ex.toString()}")
            }
        }
    }
}